﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using FreeRecorderExplorer.Properties;
using System.Threading;

namespace FreeRecorderExplorer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        BackgroundWorker bw;
        Server server;

        RecordsCollection recordings;
        RecordItem downloadingFile = null;
        bool downloadingAll = false;
        int downloadingCnt = 0; 

        private static AutoResetEvent are = new AutoResetEvent(false);

        public MainWindow()
        {
            InitializeComponent();

            bw = new BackgroundWorker();
            server = new Server();
        }


        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            this.StartServer();
            headerGrid.DataContext = server;
            //recordings = RecordsCollection.Deserialize(File.Open("recordings.xml", FileMode.Open));
            //listviewRecordings.DataContext = recordings;

            if (Settings.Default.DownloadPath != "") txtDirectory.Text = Settings.Default.DownloadPath;
            else txtDirectory.Text = Directory.GetCurrentDirectory();
            btnDownload.IsEnabled = listviewRecordings.SelectedItem != null;
            btnDownloadAll.IsEnabled = false;
        }

        private void Window_Closed_1(object sender, EventArgs e)
        {
            server.End();
        }

        private void StartServer()
        {
            BackgroundWorker bw = new BackgroundWorker();
            
            bw.DoWork += delegate
            {
                try
                {
                    server.Start();
                }
                catch (Exception exc)
                {
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        MessageBox.Show("Critical error occured. Server is down. Restart application.\r\n" + exc.Message);
                        txtConnection.Text = "Server is down. Restart application.";
                    }));
                }
            };
            bw.RunWorkerAsync();
            server.RecordingListReceived += (s, a) =>
            {
                recordings = a.Recordings;
                listviewRecordings.DataContext = recordings;
                if (!downloadingAll) btnDownloadAll.IsEnabled = true;
                else
                {                    
                    are.Set();
                }
            };

            server.DownloadStarted += delegate
            {
                txtDownloadingFile.Text = "Downloading: " + downloadingFile.Name;
                if (downloadingAll) txtDownloadingFile.Text += " (" + downloadingCnt + "/" + recordings.Count + ")";
                txtDownloadingFile.Visibility = System.Windows.Visibility.Visible;
                txtPercent.Text = "0 %";
                txtPercent.Visibility = System.Windows.Visibility.Visible;
                pbDownloading.Value = 0;
                pbDownloading.Visibility = System.Windows.Visibility.Visible;
                btnDownloadAll.IsEnabled = false;
                btnDownload.IsEnabled = false;
            };

            server.DownloadEnded += delegate
            {
                pbDownloading.Visibility = System.Windows.Visibility.Collapsed;                
                txtPercent.Visibility = System.Windows.Visibility.Collapsed;
                txtDownloadingFile.Text = "File " + downloadingFile.Name + " has been successfully downloaded";
                if (!downloadingAll)
                {
                    System.Media.SystemSounds.Asterisk.Play();
                    btnDownload.IsEnabled = true;
                    btnDownloadAll.IsEnabled = true;
                }                
                else
                {
                    downloadingCnt++;
                    are.Set();
                }
            };

            server.DownloadingProgressChanged += delegate(object sender, DownloadingProgressChangedArgs args)
            {
                pbDownloading.Value = args.Percentage;
                txtPercent.Text = args.Percentage.ToString() + " %";
            };

            server.ErrorDisconnected += delegate
            {
                pbDownloading.Visibility = System.Windows.Visibility.Collapsed;
                txtPercent.Visibility = System.Windows.Visibility.Collapsed;
                txtDownloadingFile.Visibility = System.Windows.Visibility.Collapsed;
                recordings = null;
                listviewRecordings.DataContext = null;
                btnDownloadAll.IsEnabled = false;
                if (downloadingAll)
                {
                    downloadingAll = false;
                    are.Set();
                }
            };
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnDownload_Click(object sender, RoutedEventArgs e)
        {
            if (listviewRecordings.SelectedItem == null)
            {
                MessageBox.Show("You must select recording in data grid before downloading");
                return;
            }

            var rec = (RecordItem)listviewRecordings.SelectedItem;
            downloadingFile = rec;

            string path;
            path = (Settings.Default.DownloadPath != string.Empty ?
                Settings.Default.DownloadPath : Directory.GetCurrentDirectory());

            if (File.Exists(path + "\\" + rec.Name))
            {
                if (showQuestion("File " + rec.Name + " already exists in current path (" + path + "). Do you want overwrite it?")
                    == MessageBoxResult.No) return;
            }

            server.DownloadRecording(rec.Name);
        }


        private void btnDownloadAll_Click(object sender, RoutedEventArgs e)
        {            
            string path;
            path = (Settings.Default.DownloadPath != string.Empty ?
                Settings.Default.DownloadPath : Directory.GetCurrentDirectory());

            var rec_exists = this.recordings.Where(r => File.Exists(System.IO.Path.Combine(path, r.Name))).ToList();
            
            string file_list = "";

            if (rec_exists.Count > 0)
            {
                foreach (var rec in rec_exists)
                {
                    file_list += rec.Name + "\r\n";		 
                }
                if (showQuestion("Some files already exist in current path (" + path + "). Do you want overwrite them?\r\n" + 
                    "Files:\r\n" + file_list)
                    == MessageBoxResult.No) return;
            }
            
            btnDownloadAll.IsEnabled = false;
            downloadingCnt = 1;            

            var recs = recordings;
            BackgroundWorker bw = new BackgroundWorker();            
            bw.DoWork += delegate
            {
                foreach (var rec in recs)
                {
                    downloadingFile = rec;
                    server.DownloadRecording(rec.Name);
                    are.WaitOne(-1);
                    if (!downloadingAll) return;

                }
                System.Media.SystemSounds.Asterisk.Play();
                downloadingAll = false;
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    btnDownloadAll.IsEnabled = true;
                    btnDownload.IsEnabled = true;
                }));
                
            };
            downloadingAll = true;
            bw.RunWorkerAsync();

        }

        private void btnChangeDir_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK && dialog.SelectedPath != "")
            {
                Settings.Default.DownloadPath = dialog.SelectedPath;
                Settings.Default.Save();
                txtDirectory.Text = dialog.SelectedPath;
            }
        }

        private void listviewRecordings_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnDownload.IsEnabled = listviewRecordings.SelectedItem != null;
        }

        private void btnConnection_Click(object sender, RoutedEventArgs e)
        {
            ConnectionWindow win = new ConnectionWindow();
            win.ShowDialog();
        }

        private MessageBoxResult showQuestion(string msg)
        {
            return MessageBox.Show(msg, "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);
        }

        private void btnInfo_Click(object sender, RoutedEventArgs e)
        {
            InfoWindow win = new InfoWindow();
            win.ShowDialog();
        }

    }
}
